/**
 *******************************************************************************
 * \brief   CAS EBX Project Work "Kaffeemaschine"
 *
 * \file    programming.c
 * \version 1.0
 * \date    30.06.2010
 * \author  Baehler Thomas, Liechti Beat, Sauter Marc
 * \author  Vuksic Valentina, Zbinden Rene
 *
 * \remark  Last Modifications:
 * \remark  V1.0, 30.06.2010   Initial release
 *******************************************************************************
 **/

/*
 *******************************************************************************
 * Definitions
 *******************************************************************************
 */


/*
 *******************************************************************************
 * Imports
 *******************************************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>

#include "coffee2.h"
#include "channel.h"
#include "pool.h"
#include "device.h"

/*
 *******************************************************************************
 * Local Variables
 *******************************************************************************
 */
static tChannel /**c2,*/ *c4;
static tPool *p2;
static tDevice *d2;
static int timeExpired;


/*
 *******************************************************************************
 * Local Function Declaration
 *******************************************************************************
 */
static void sigtermHandler(int signal);
static void setTimeExpired(int signal);


/**
 *******************************************************************************
 * sigtermHandler
 *
 * \brief handle SIGTERM signal, close all pools and channels and exit
 *
 *******************************************************************************
 **/
static void sigtermHandler(int signal) {
	syslog(LOG_INFO, "SIGTERM reveiced, stopping ...");
	/* close channels and pools */
	//closeChannel(c2);
	closeDevice(d2);
	closeChannel(c4);
	closePool(p2);
	/* close syslog */
	closelog();
	/* close and remove the runfile */
	exit(EXIT_SUCCESS);
}


/**
 *******************************************************************************
 * setTimeExpired
 *
 * \brief handle SIGALRM signal, set timeExpired
 *
 *******************************************************************************
 **/
static void setTimeExpired(int signal) {
	timeExpired = 1;
	return;
}


/**
 *******************************************************************************
 * mainProgramming
 *
 * \brief Activity: "Progr."
 *
 * \return pid
 *
 *******************************************************************************
 **/
pid_t mainProgramming(){
	pid_t pid;
	sigset_t sigmask;
	struct sigaction sigtermAction, defaultAction;
	int parameter, c4Message;

	pid = fork();
	if (pid == 0) {
		/* syslog */
		closelog();
		openlog("coffee-programming", LOG_PID, LOG_DAEMON);
		/* block all signals other than SIGTERM */
		sigemptyset(&sigmask);
		sigaddset(&sigmask, SIGTERM);
		sigtermAction.sa_handler = sigtermHandler;
		sigtermAction.sa_mask = sigmask;
		if (sigaction(SIGTERM, &sigtermAction, &defaultAction) == -1){
			syslog(LOG_ERR, "unable to setup signal handling!");;
		}
		/* register alarm function */
		if (signal(SIGALRM, setTimeExpired) == SIG_ERR) {
			syslog(LOG_ERR, "can't register SIGALRM!");
		}
		/* open channels and pools */
		//c2 = openChannelRead("C2", sizeof(int)); /* read from "Device" */
		d2 = openDeviceRead("/dev/c2service");
		c4 = openChannelRead("C4", sizeof(int)); /* read from
														"User Interface" */
		p2 = openPool("P2", sizeof(parameter)); /* "Parameter" */

		while (1) {
			if (readChannel(c4, &c4Message) > 0 ) {
				syslog(LOG_INFO, "programming from device input");
				alarm(WAIT_FOR_MILK_TIMEOUT);
				//while (readChannel(c2, &parameter) <= 0 && timeExpired == 0) {
				for (readDevice(d2, &parameter);
						parameter <= 0 && timeExpired == 0;
						readDevice(d2, &parameter)) {
					usleep(500);
				}
				alarm(0);
				if (timeExpired == 1) {
					/* just logging, we go not in error state no device is
					 * inserted */
					syslog(LOG_INFO, "there was no device input");
				}
				else {
					syslog(LOG_INFO, "saving new parameters");
					writeToPool(p2, &parameter);
				}
			}
			usleep(500);
		}
	}
	return pid;
}
